function [vec, dpcc, rall, pos] = scan_dpc_data(fid,nn)

extractcell = @(c) c{1};
cell2char = @(c) [char(c) ,repmat(' ',numel(c),1)].';
cell2doub = @(c) extractcell(textscan(cell2char(c),'%f'));


[scanc, pos] = textscan(fid, '%[^/ \n\t]', nn, 'CommentStyle', '--', ...
    'WhiteSpace', ' \r\n\t', ...
    'MultipleDelimsAsOne', true);
scanc=extractcell(scanc);


%{
[scanc, pos]:
scanc 是 textscan 的输出，通常是一个单元数组，包含读取的数据内容。
pos 是文件指针在读取结束后的位置，表示文件读取到的位置，可以用来记录读取的进度。

fid:
这是文件标识符，是通过 fopen 打开的文件句柄，指向要读取的文件。

'%[^/ \n\t]':
这是格式说明符，指定要读取的数据格式。
% 表示这是格式化输入。
[^/ \n\t] 表示读取除了 /、换行符 (\n)、制表符 (\t) 和空格 (' ') 之外的所有字符，直到遇到这些字符之一时停止读取。
也就是说，textscan 将从文件中读取每个字段，直到遇到 /、换行符、制表符或空格为止。

nn:
nn 是一个整数，指定要读取的最大字段数（通常是你希望 textscan 读取的最大次数）。也就是说，textscan 将最多读取 nn 个符合格式的字段。

'CommentStyle', '--':
这意味着在文件中，所有以 -- 开头的行都会被视为注释，textscan 在读取数据时会忽略这些行。
例如，行 -- This is a comment 将不会被读取。

'WhiteSpace', ' \r\n\t':
这指定了空白字符的集合。在这个例子中，空格 (' ')、回车符 ('\r')、换行符 ('\n')、和制表符 ('\t') 都被视为空白字符。在读取数据时，遇到这些字符时会将它们跳过，不作为数据的一部分读取。

'MultipleDelimsAsOne', true:
这个选项指定如果有多个连续的分隔符或空白字符（比如连续多个空格或制表符），它们将被视为一个分隔符，避免空字段的产生。例如，数据中连续多个空格会被看作一个空格，而不会导致多个空白字符被读取。
%}

dpc = regexp(scanc, '(\d+)\*(\S+)', 'tokens');
dpci   = ~cellfun('isempty', dpc);
%{
regexp:

regexp 是 MATLAB 中用于基于正则表达式进行文本匹配的函数。它可以用来查找、提取或者替换文本中的特定模式。
'(\d+)\*(\S+)':

这是正则表达式模式，描述了要在 scanc 中查找的内容。
\d+: 匹配一个或多个数字。\d 表示数字，+ 表示一个或多个数字。
\*: 匹配星号字符 *。由于 * 是正则表达式中的特殊符号，必须使用反斜杠 \ 进行转义。
\S+: 匹配一个或多个非空白字符。\S 表示非空白字符，+ 表示一个或多个。
(): 小括号用于分组，表示要提取的内容，即数字部分和非空白字符部分。
这个正则表达式的作用是：匹配格式为“数字 + 星号 + 非空白字符”的模式。例如，匹配 12*abc 或 5*xyz123 等形式。

'tokens':

'tokens' 是 regexp 函数的选项，表示提取匹配的分组内容（即正则表达式中用 () 括起来的部分）。
在这个例子中，会提取两部分内容：第一部分是数字（\d+），第二部分是非空白字符（\S+）

%}
dpcc = ones(numel(scanc),1); % 每个值至少重复一次
if any(dpci) % 如果存在N*数值(N>=2)的情况
    dpc1=vertcat(dpc{dpci});
    dpc2=vertcat(dpc1{:});
    dpcc(dpci) = cell2doub(dpc2(:,1));
    scanc(dpci) = dpc2(:,2);
end
vec=cell2doub(scanc);

rall= sum(dpcc)==nn;
